package com.wh1200.mybatis.xmlless.config

import com.wh1200.mybatis.xmlless.model.Properties
import com.wh1200.mybatis.xmlless.resolver.ColumnsResolver
import com.wh1200.xmlless.test.dao.StudentJavaDAO
import com.wh1200.xmlless.test.model.Student
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import kotlin.reflect.jvm.javaMethod
import kotlin.test.assertContains
import kotlin.test.assertNotNull


/**
 *
 * Created by 吴昊 on 2018-12-09.
 *
 * @author 吴昊
 * @since 0.0.1
 */
class StudentJavaDAOResolverTest : BaseResolverTest(
    StudentJavaDAO::class.java
) {

  @Test
  fun deleteByIds() {
    val method = StudentJavaDAO::deleteByIds.javaMethod!!
    val q = createQueryForMethod(method)
    val sql = q.sql
    assertNotNull(sql)
    assert(!sql.contains("<if "))
    assertContains(sql, "<foreach collection=\"ids\"")
  }

  @Test
  @DisplayName("解析包含多表关联的持久化对象的字段映射")
  fun resolveColumns() {
    val methodInfo = createMethodInfo(StudentJavaDAO::findById.javaMethod!!)
    val cols = ColumnsResolver.resolveSelectColumns(Properties(), methodInfo).map {
      it.toSql()
    }
    assertContains(cols, "createUser.name AS createUserName")
    assertContains(cols, "id_t_score.score AS scores_score")
    assertContains(cols, "id_t_score.subject_id AS scores_subjectId")
    assertContains(cols, "id_t_score_subject_id_subject.id AS scores_subject_id")
    assertContains(cols, "id_t_score_subject_id_subject.name AS scores_subject_name")
    assertContains(cols, "t_student.update_user_id AS updateUserId")
    assert(!cols.contains("t_student.update_user_name AS updateUserName"))
    assertContains(cols, "updateUser.name AS updateUserName")
    assertContains(cols, "u.name AS userName")
  }

  @Test
  fun saveAll() {
    class A {

      var a: List<String> = listOf()
      val b: Array<String>? = null
      var c: IntArray? = null
      var d: ByteArray? = null

    }
    A::class.java.declaredFields.forEach {
      println(it.name + "/" + Collection::class.java.isAssignableFrom(it.type).toString() + "/" + it.type.isArray)
    }
    val sql = createQueryForMethod(StudentJavaDAO::saveAll.javaMethod!!).sql
    assertNotNull(sql)
  }

  @Test
  @DisplayName("测试多表关联以及多级关联的结果映射")
  fun resolveResultMap() {
    createQueryForMethod(StudentJavaDAO::findById.javaMethod!!)
    val resultMaps = builderAssistant.configuration.resultMaps
    val ids = resultMaps.map { it.id }
    assert(ids.contains(buildResultMapId(StudentJavaDAO::findById.javaMethod!!)))
    assert(ids.contains("${buildResultMapId(StudentJavaDAO::findById.javaMethod!!)}_scores"))
    assert(ids.contains("${buildResultMapId(StudentJavaDAO::findById.javaMethod!!)}_scores_subject"))
    val scoreMap = resultMaps.first { it.id == "${buildResultMapId(StudentJavaDAO::findById.javaMethod!!)}_scores" }
    assert(scoreMap.hasNestedResultMaps())
    val resultMappings = scoreMap.propertyResultMappings
    assert(resultMappings.any { it.column == "subjectId" })
    assert(resultMappings.any { it.property == "subject" })
  }

}
